# LuckPay Web Manage System
#
# Copyright (c) 2016 Lucky Byte, Inc.
#
express = require 'express'
pgsql   = require 'pg'
uuid    = require 'uuid'
moment  = require 'moment'
router = express.Router()
module.exports = router


router.all '/', (req, res, next) ->
    where_clause = """(
        case
        when t1.chnl in (1,4) then
            json_extract_path_text(t1.i_pkt, '42') like $1 or
            json_extract_path_text(t1.i_pkt, '41') like $1 or
            json_extract_path_text(t1.i_pkt, '4')  like $1 or
            json_extract_path_text(t1.i_pkt, '11') like $1
        end or
        case
        when t2.chnl = 3 then
            json_extract_path_text(t2.i_pkt, 'merId') like $1 or
            json_extract_path_text(t2.i_pkt, 'orderId') like $1
        end
    )"""

    await pgsql.connect settings.pgsql_url, defer err, client, done
    if err then done(client); return next(err)

    await client.query "select count(*)::int as count
        from pay_t40_recvr as r
        left join pay_trlist as t1 on
            t1.uuid = r.tr_uuid_1 and t1.incoming = true
        left join pay_trlist as t2 on
            t2.uuid = r.tr_uuid_2 and t2.incoming = false
        where #{where_clause} and
            r.ctime::date = CURRENT_DATE and r.checked = false", [
            '%' + res.locals.keyword + '%'
        ], defer err, result
    if err then done(client); return next(err)
    res.locals.total = result.rows[0].count

    await client.query "select r.*,
        t1.sys_time as tr1_systime,
        case
        when t1.chnl in (1,4) then
            array[
                json_extract_path_text(t1.i_pkt, '42'),
                json_extract_path_text(t1.i_pkt, '41'),
                json_extract_path_text(t1.i_pkt, '4'),
                json_extract_path_text(t1.i_pkt, '11')]
        end as tr1_info,
        case
        when t2.chnl = 3 then
            array[
                json_extract_path_text(t2.i_pkt, 'merId'),
                json_extract_path_text(t2.i_pkt, 'orderId'),
                json_extract_path_text(t2.i_pkt, 'txnAmt')]
        end as tr2_info,
        t2.n_pkt is not null as tr2_confirm,
        t2.notes as tr2_notes
        from pay_t40_recvr as r
        left join pay_trlist as t1 on
            t1.uuid = r.tr_uuid_1 and t1.incoming = true
        left join pay_trlist as t2 on
            t2.uuid = r.tr_uuid_2 and t2.incoming = false
        where #{where_clause} and
            r.ctime::date = CURRENT_DATE and r.checked = false
        order by r.serial offset $2 limit $3", [
            '%' + res.locals.keyword + '%'
            res.locals.offset, res.locals.page_rows
        ], defer err, result
    if err then done(client); return next(err)
    done()
    res.locals.records = result.rows
    res.render 't40_recvr/index'


query_info = (req, res, next) ->
    await pgsql.connect settings.pgsql_url, defer err, client, done
    if err then done(client); return next(err)

    await client.query "select r.*,
        t1.sys_time as tr1_systime,
        json_extract_path_text(t1.merch, 'name') as tr1_mername,
        case
        when t1.chnl in (1,4) then
            array[
                json_extract_path_text(t1.i_pkt, '42'),
                json_extract_path_text(t1.i_pkt, '41'),
                json_extract_path_text(t1.i_pkt, '4'),
                json_extract_path_text(t1.i_pkt, '11')]
        end as tr1_info,
        case r.product
        when 'p1' then o1.p1_fee
        when 'p2' then o2.p2_fee
        end as fee,
        case r.product
        when 'p1' then (
            select array[
                    pay_chnl::text, pay_merid,
                    acct_no, acct_name, acct_cred_type::text, acct_cred_no
                ] from pay_p1 as p1 where p1.uuid = o1.p1_uuid
            )
        when 'p2' then (
            select array[
                    pay_chnl::text, pay_merid,
                    acct_no, acct_name, acct_cred_type::text, acct_cred_no,
                    p2_fund, fee_take_type::text, fund_lack_proc::text,
                    p2f.overdraw::text
                ] from pay_p2 as p2
                    left join pay_p2_fund as p2f on p2f.uuid = p2.p2_fund
                    where p2.uuid = o2.p2_uuid
            )
        end as order_conf,
        u.realname as input_user
        from pay_t40_recvr as r
        left join pay_trlist as t1 on
            t1.uuid = r.tr_uuid_1 and t1.incoming = true
        left join pay_p1_order as o1 on o1.uuid = r.order_uuid
        left join pay_p2_order as o2 on o2.uuid = r.order_uuid
        left join web_users as u on u.uuid = r.inputer
        where r.uuid = $1 and r.ctime::date = CURRENT_DATE and
            r.checked = false and r.done = false", [
            req.params.id
        ], defer err, result
    if err then done(client); return next(err)

    if result.rows.length == 0
        done()
        return next new Error('没有查询到追付记录，请检查.')

    record = result.rows[0]

    # 计算追付金额
    # 如果是消费代付，追付金额为原交易金额 - 手续费
    # 如果是助农取款代付，手续费可能从资金池扣取，因此追付金额显示为原消费金额
    req.body.pay_amt = parseFloat(record.tr1_info[2]) / 100
    if record.product is 'p1'
        req.body.pay_amt = req.body.pay_amt - record.fee

    # 四舍五入
    req.body.pay_amt = Math.round(req.body.pay_amt * 100) / 100

    # 查询代付商户信息
    await client.query "select * from pay_merch where uuid = $1", [
        record.order_conf[1]
    ], defer err, result
    if err then done(client); return next(err)
    record.pay_merch = result.rows[0]

    # 查询助农代付资金池
    await client.query "select * from pay_p2_fund where uuid = $1", [
        record.order_conf[6]
    ], defer err, result
    if err then done(client); return next(err)
    record.p2_fund = result.rows[0]
    done()

    res.locals.record = record
    next()


check_retrefno = (req, res, next) ->
    for k in ['uuid', 't40_amt', 'pay_chnl', 'pay_merid', 'acct_no', 'retrefno']
        return next(new Error("请求缺少参数[#{k}]")) if not req.body[k]

    await pgsql.connect settings.pgsql_url, defer err, client, done
    if err then done(client); return next(err)

    # 确认检索参考号与消费交易匹配
    await client.query "select
        case
        when t1.chnl in (1,4) then
            json_extract_path_text(t1.o_pkt, '37')
        end as retrefno
        from pay_t40_recvr as r
        left join pay_trlist as t1 on
            t1.uuid = r.tr_uuid_1 and t1.incoming = true
        where r.uuid = $1", [
            req.body.uuid
        ], defer err, result
    if err then done(client); return next(err)
    done()

    if result.rows.length == 0
        return next new Error("未查询到追付记录[#{req.body.uuid}].")

    if result.rows[0].retrefno isnt req.body.retrefno
        return next new Error('原交易检索参考号不匹配，不能代付')
    next()


router.get '/new/:id', query_info, (req, res, next) ->
    res.locals.breadcrumbs.push 'title': '请求追付'

    # 不允许重复追付
    if res.locals.record.inputed
        return next new Error('该记录已被追付，不允许重复追付')

    res.locals.record.t40_amt = req.body.pay_amt
    return res.render 't40_recvr/new'


router.post '/new', check_retrefno, (req, res, next) ->
    await pgsql.connect settings.pgsql_url, defer err, client, done
    if err then done(client); return next(err)

    t40_amt = parseFloat(req.body.t40_amt.replace(/,/g, '')) or -1
    return next new Error('追付金额必须为正数.') if t40_amt <= 0.0

    if req.body.fund_overdraw
        overdraw = parseFloat(req.body.fund_overdraw.replace(/,/g, '')) or 0.0

    # 更新追付记录
    await client.query "update pay_t40_recvr set
        t40_amt = $1, pay_chnl = $2, pay_merid = $3,
        acct_no = $4, acct_name = $5, acct_cred_type = $6, acct_cred_no = $7,
        p2_fund = $8, fee_take_type = $9, fund_lack_proc = $10,
        fund_overdraw = $11,
        inputed = true, inputer = $12, input_time = CURRENT_TIMESTAMP
        where uuid = $13", [
            t40_amt
            parseInt(req.body.pay_chnl)
            req.body.pay_merid
            req.body.acct_no
            req.body.acct_name
            parseInt(req.body.acct_cred_type)
            req.body.acct_cred_no
            req.body.p2_fund
            req.body.fee_take_type
            req.body.fund_lack_proc
            overdraw
            req.session.userinfo.uuid
            req.body.uuid
        ], defer err, result
    if err then done(client); return next(err)
    done()
    res.redirect '/t40_recvr'


router.get '/check/:id', query_info, (req, res, next) ->
    res.locals.breadcrumbs.push 'title': '确认追付'

    if not res.locals.record.inputed
        return next new Error('该记录尚未追付，不能复核')
    if res.locals.record.checked
        return next new Error('该记录已复核，不能重复复核')

    # 检查关键要素是否一致
    record = res.locals.record
    if (
        parseFloat(record.t40_amt) isnt req.body.pay_amt or
        parseInt(record.pay_chnl) isnt parseInt(record.order_conf[0]) or
        record.pay_merid isnt record.order_conf[1] or
        record.acct_no   isnt record.order_conf[2]
        )
        await pgsql.connect settings.pgsql_url, defer err, client, done
        if err then done(client); return next(err)

        await client.query "update pay_t40_recvr set inputed = false
            where uuid = $1", [
                req.params.id
            ], defer err, result
        if err then done(client); return next(err)
        done()
        return next new Error(
            '追付信息不一致，不能追付，请检查是否修改了消费代付配置信息，系统已退回此追付记录')

    res.render 't40_recvr/check'


router.post '/check', check_retrefno, (req, res, next) ->
    await pgsql.connect settings.pgsql_url, defer err, client, done
    if err then done(client); return next(err)

    # 更新追付记录
    await client.query "update pay_t40_recvr set
        checked = true, checker = $1, check_time = CURRENT_TIMESTAMP,
        notes = '已确认追付，等待调度'
        where uuid = $2", [
            req.session.userinfo.uuid
            req.body.uuid
        ], defer err, result
    if err then done(client); return next(err)
    done()
    res.redirect '/t40_recvr'
